import { Component, Vue, Emit } from 'vue-property-decorator';
import { isString } from "lodash";
import { superFun } from '@/utils/Annotate'
/**
 * 这是一个表单mixin类
 * 提供了一些表单提交数据的通用方法
 */
@Component({
})
export class mixinViewForm extends Vue {

    /**
     * 定义submitSuccess事件
     * 一般在提交数据成功后出发
     *
     * @memberof mixinViewForm
     */
    @Emit('submitSuccess') submitSuccess() {
    }

    // 表单数据
    // 表单组件需要如下设置 :model="formData"
    formData: any = {
    };

    /**
     *
     * 触发submitSuccess事件
     * 事件触发前如果需要处理一些交互逻辑
     * 可以定义一个successAfter方法
     *
     * @param {*} data 事件传递参数
     * @memberof mixinViewForm
     */
    @superFun()
    submitFormSuccess(data: any) {
        const me = this as any;
        // 检查是否有successAfter方法，如果有就执行
        me.successAfter && me.successAfter(data);
        me.submitSuccess(data);
    }

    /**
     *
     *
     * @param {string} mes 提示消息，如果有值会弹出确认弹窗
     * @memberof mixinViewForm
     */
    /**
     * 验证表单并提交formData中的数据
     * 会根据isEdit配置调用不同的方法去提交数据
     * 需要定义好 itemAdd 和 itemEdit 方法
     *
     * @param {*} [{
     * mes = "",提示消息，如果有值会弹出确认弹窗
     * isContinue = false 是否继续，如果继续将不会关闭弹窗
     * }={}]
     * @memberof mixinViewForm
     */
    onSubmit({ mes = "", isContinue = false }: any = {}) {
        const me = this as any,
            // 提交表单会根据isEdit配置调用不同的方法去提交数据
            submitFun = me.isEdit ? me.itemEdit : me.itemAdd, formData = me.formData;
        // 验证表单并提交指定数据
        me.submitForm(submitFun, formData, {
            mes
        }).then(({ data }: any = {}) => {
            if (isContinue) {
                // 重置表单数据
                me.resetForm();
            }
            // todo { resData: data, formData: formData } 为预留数据，还未使用
            me.submitFormSuccess({ resData: data, formData: formData, isContinue });
        });
    }

    /**
     * 验证表单并提交指定数据
     * 忽略catch
     *
     * @param {Function} submitFun 提交方法 Promise类型
     * @param {*} params 数据
     * @param {*} [{
     *         ref = 'form', 表单ref配置
     *         mes = '' 提示消息，如果有值会弹出确认弹窗
     *     }={}]
     * @return {*}  {*} Promise
     * @memberof mixinViewForm
     */
    submitForm(submitFun: Function, params: any, {
        ref = 'form',
        mes = ''
    }: any = {}): any {
        return new Promise((resolve) => {
            const me = this as any, form = me.$refs[ref];
            // 验证表单
            form.validate((valid: any) => {
                if (valid) {
                    // 判断是否需要弹出确认弹窗
                    if (mes && isString(mes)) {
                        me.$confirm(mes, "提示", {
                            confirmButtonClass: "btn-blue"
                        }).then(() => {
                            // 提交数据
                            submitFun(params).then((res: any) => {
                                resolve(res);
                            })
                        });
                    } else {
                        // 提交数据
                        submitFun(params).then((res: any) => {
                            resolve(res);
                        })
                    }
                }
            });
        }).catch(() => { });
    }

    /**
     * 验证部分表单
     *
     * @param {*} validateList 验证字段集合 例 ["username", "password", "code"]
     * @param {string} [formName="form"] 表单ref配置
     * @return {*} Promise
     * @memberof mixinViewForm
     */
    validateForm(validateList: any, formName: string = "form"): any {
        return new Promise((resolve, reject) => {
            const me = this as any,
                form = me.$refs[formName];
            let is = true;
            form.validateField(validateList, function (v: any) {
                v ? (is = false) : "";
            });
            if (is) {
                resolve({});
            } else {
                reject();
            }
        });
    }

    /**
     *  验证部分表单并提交指定数据
     *
     * @param {*} validateList 验证字段集合 例 ["username", "password", "code"]
     * @param {*} submitFun 提交方法 Promise类型
     * @param {*} params 数据
     * @return {*} Promise
     * @memberof mixinViewForm
     */
    submitFormBack(validateList: any, submitFun: any, params: any): any {
        return new Promise((resolve, reject) => {
            const me = this as any;
            // 验证部分表单
            me.validateForm(validateList)
                .then(() => {
                    // 提交数据
                    submitFun(params)
                        // 成功
                        .then((res: any) => {
                            resolve(res);
                        })
                        // 失败
                        .catch(() => {
                            reject();
                        });
                })
                // 失败
                .catch(() => {
                    reject();
                });
        });
    }

    /**
     * 验证部分表单并提交formData中的数据
     *
     * @param {*} validateList 验证字段集合 例 ["username", "password", "code"]
     * @param {*} submitFun 提交方法 Promise类型
     * @return {*}
     * @memberof mixinViewForm
     */
    submitFormDataBack(validateList: any, submitFun: any): any {
        const me = this as any;
        return me.submitFormBack(validateList, submitFun, me.formData)
    }

    /**
     * 重置表单
     *
     * @param {string} [refName="form"] 表单ref
     * @memberof mixinViewForm
     */
    resetForm(refName: string = "form") {
        const me = this as any,
            // 获取表单对象
            ref = me.$refs[refName];
        // 重置表单数据
        ref && ref.resetFields();
    }
}
